using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SBPweb.Themes.Windows.Skins;

namespace SBPweb.Controls.Windows.Common
{
	/// <summary>
	/// Class of DesignerButton
	/// </summary>
	[ToolboxBitmap(typeof(System.Windows.Forms.Button))]
	public partial class DesignerButton : System.Windows.Forms.Button
	{

		#region Private fields

		private Color mButtonColor = Color.Transparent;
		private Margin mSizingMargin;
		private Margin mContentMargin;
		private bool mIsHover = false;
		private bool mIsDown = false;
		private SizeF size;
		private System.Drawing.Size mImageOffset;

		#endregion

		public DesignerButton()
		{
			InitializeComponent();
			SetStyle();
		}

		#region Custom draw

		private void SetStyle()
		{
			mSizingMargin = new Margin(new Padding(0, 0, 0, 0));
			mContentMargin = new Margin(new Padding(5, 5, 5, 5));
			base.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			base.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			base.OnPaintBackground(pe);
			//base.OnPaint(pe);

			Rectangle rectOuter = this.ClientRectangle;
			Rectangle rectInner = this.ClientRectangle;
			rectInner.Y += 2;
			rectInner.X += 2;
			rectInner.Width -= 4;
			rectInner.Height -= 4;
			if (this.mIsDown)
			{
				pe.Graphics.FillEllipse(new SolidBrush(this.FlatAppearance.MouseDownBackColor), rectInner);
			}
			else
			if (this.mIsHover)
			{
				pe.Graphics.FillEllipse(new SolidBrush(this.FlatAppearance.MouseOverBackColor), rectInner);
			}
			else
			{
				pe.Graphics.FillEllipse(new SolidBrush(this.ButtonColor), rectInner);
			}
			pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
			pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;

			System.Drawing.Size sizeHalf = new System.Drawing.Size(this.Image.Size.Width / 2, this.Image.Size.Height / 2);
			Point point = new Point(rectOuter.Left + rectOuter.Width / 2, rectOuter.Top + rectOuter.Height / 2);
			point = Point.Add(Point.Subtract(point, sizeHalf), ImageOffset);
			pe.Graphics.DrawImageUnscaled(this.Image, point);

			this.DrawText(pe);

			pe.Graphics.DrawImage(global::SBPweb.Controls.Windows.Properties.Resources.Designer_Button_64x64, rectOuter);
		}

		protected override void OnPaintBackground(PaintEventArgs e)
		{
			base.OnPaintBackground(e);
		}

		private void DrawText(PaintEventArgs e)
		{
			StringFormat sf = new StringFormat(StringFormat.GenericDefault);
			string text = this.Text;
			string textStart = string.Empty;
			string textShCut = string.Empty;
			int pos = text.IndexOf("&");
			if (pos != -1)
			{
				text = text.Remove(pos, 1);
				textStart = text.Substring(0, pos);
				textShCut = text.Substring(pos, 1);
			}
			size = e.Graphics.MeasureString(text, this.Font, new SizeF(e.ClipRectangle.Width, e.ClipRectangle.Height), sf);
			SizeF sizeStart = e.Graphics.MeasureString(textStart, this.Font, new SizeF(e.ClipRectangle.Width, e.ClipRectangle.Height), sf);
			SizeF sizeShCut = e.Graphics.MeasureString(textShCut, this.Font, new SizeF(e.ClipRectangle.Width, e.ClipRectangle.Height), sf);

			float xLeft, xCenter, xRight, yTop, yMiddle, yBottom;
			float textX, textY;

			int canvasWidth = e.ClipRectangle.Width - mSizingMargin.Horizontal - mContentMargin.Horizontal;
			int canvasHeight = e.ClipRectangle.Height - mSizingMargin.Vertical - mContentMargin.Vertical;

			xLeft = mSizingMargin.Left + mContentMargin.Left;
			xCenter = (canvasWidth - size.Width) / 2 + mSizingMargin.Left + mContentMargin.Left;
			xRight = canvasWidth - size.Width + mSizingMargin.Right + mContentMargin.Right;

			yTop = mSizingMargin.Top + mContentMargin.Top;
			yMiddle = (canvasHeight - size.Height) / 2 + mSizingMargin.Top + mContentMargin.Top;
			yBottom = canvasHeight - size.Height + mSizingMargin.Bottom + mContentMargin.Bottom;

			switch (this.TextAlign)
			{
				case ContentAlignment.TopLeft:
					textX = xLeft;
					textY = yTop;
					break;
				case ContentAlignment.TopCenter:
					textX = xCenter;
					textY = yTop;
					break;
				case ContentAlignment.TopRight:
					textX = xRight;
					textY = yTop;
					break;
				case ContentAlignment.MiddleLeft:
					textX = xLeft;
					textY = yMiddle;
					break;
				case ContentAlignment.MiddleCenter:
					textX = xCenter;
					textY = yMiddle;
					break;
				case ContentAlignment.MiddleRight:
					textX = xRight;
					textY = yMiddle;
					break;
				case ContentAlignment.BottomLeft:
					textX = xLeft;
					textY = yBottom;
					break;
				case ContentAlignment.BottomCenter:
					textX = xCenter;
					textY = yBottom;
					break;
				case ContentAlignment.BottomRight:
					textX = xRight;
					textY = yBottom;
					break;
				default:
					textX = 0;
					textY = 0;
					break;
			}

			e.Graphics.DrawString(text, this.Font, new SolidBrush(this.ForeColor), new RectangleF(textX, textY, textX + size.Width, textY + size.Height));
			if (pos != -1)
			{
				e.Graphics.DrawLine(new Pen(this.ForeColor), textX + sizeStart.Width + 1, textY + size.Height, textX + sizeStart.Width + sizeShCut.Width - 2, textY + size.Height);
			}

			// Set minimum size
			this.MinimumSize = new System.Drawing.Size(Convert.ToInt32(/*mSizingMargin.Horizontal + */mContentMargin.Vertical + size.Width + 5), Convert.ToInt32(/*mSizingMargin.Vertical + */mContentMargin.Vertical + size.Height + 5));
		}

		#endregion

		#region Public property accessors

		[Browsable(false)]
		public new FlatStyle FlatStyle
		{
			get
			{
				return base.FlatStyle;
			}
		}

		[Category("Appearance")]
		public Color ButtonColor
		{
			get
			{
				return mButtonColor;
			}
			set
			{
				mButtonColor = value;
				Invalidate();
			}
		}

		[Category("Appearance")]
		public System.Drawing.Size ImageOffset
		{
			get
			{
				return mImageOffset;
			}
			set
			{
				mImageOffset = value;
				Invalidate();
			}
		}

		#endregion

		#region Event handlers

		protected override void OnMouseEnter(EventArgs e)
		{
			base.OnMouseEnter(e);
			this.mIsHover = true;
			this.Invalidate();
		}

		protected override void OnMouseLeave(EventArgs e)
		{
			base.OnMouseLeave(e);
			this.mIsHover = false;
			this.Invalidate();
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown(e);
			this.mIsDown = true;
			this.Invalidate();
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			base.OnMouseUp(e);
			this.mIsDown = false;
			this.Invalidate();
		}

		#endregion

	}
}
